package com.elow.testffmpeg;

import androidx.appcompat.app.AppCompatActivity;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class OpenGLTestActivity extends AppCompatActivity {

    private GLSurfaceView glSurfaceView;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        glSurfaceView = new GLSurfaceView(this);

        // Create an OpenGL ES 2.0 context
        glSurfaceView.setEGLContextClientVersion(2);

        glSurfaceView.setRenderer(new GLSurfaceView.Renderer() {

            //三角形坐标
            private float coords[] = {
                    0.0f, 1.0f, 0.0f,  // top 屏幕顶端中心点
                    -1.0f, -1.0f, 0.0f, // bottom left 屏幕底部左下角
                    1.0f, -1.0f, 0.0f   // bottom right 屏幕底部右下角
            };

            //颜色
            private float color[]={0.63671875f, 0.76953125f, 0.22265625f, 1.0f};
            private int mProgram;

            FloatBuffer fb;

            /**
             * 顶点着色器代码
             * attribute变量(属性变量)只能用于顶点着色器中
             * uniforms变量(一致变量)用来将数据值从应用程其序传递到顶点着色器或者片元着色器。 。
             * varying变量(易变变量)是从顶点着色器传递到片元着色器的数据变量。
             * gl_Position （必须）为内建变量，表示变换后点的空间位置。
             */
            private final String vertexShaderCode =
                    "attribute vec4 vPosition;" +  // 应用程序传入顶点着色器的顶点位置
                            "void main() {" +
                            "  gl_Position = vPosition;" + // 设置此次绘制此顶点位置
                            "}";

            /**
             * 片元着色器代码
             */
            private final String fragmentShaderCode =
                    "precision mediump float;" +  // 设置工作精度
                            "uniform vec4 vColor;" +  // 应用程序传入着色器的颜色变量
                            "void main() {" +
                            "  gl_FragColor = vColor;" + // 颜色值传给 gl_FragColor内建变量，完成片元的着色
                            "}";


            @Override
            public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
/*
                1、创建缓存区，*4是因为float类型是4字节
                2、用用的是系统缓存，而不是应用缓存
                3、缓存存储完毕以后使用position将位置索引指在第一位。
                */
                fb = BufferUtil.fBuffer(coords);


                /*
                加载预编译的代码，这个代码使用字符串写的
                这里的字符串是GLSL语言
                就是将该语言的代码预制好，方便后面设置定点的时候调用
                 */

                //加载预编译顶点渲染器
                int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);


                int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

                /*
                创建一个运行程序
                将上面预编译的顶点和片源的渲染器放到新程序里面
                让程序和GLSL创建连接
                 */
                mProgram = GLES20.glCreateProgram();

                GLES20.glAttachShader(mProgram,vertexShader);
                GLES20.glAttachShader(mProgram,fragmentShader);

                GLES20.glLinkProgram(mProgram);
            }

            @Override
            public void onSurfaceChanged(GL10 gl10, int i, int i1) {

            }

            @Override
            public void onDrawFrame(GL10 gl10) {





                //上面是准备工作，下面开始进行绘制
                GLES20.glUseProgram(mProgram);
                //获取当前glsl的programe下面的 position地址，这样后面方斌啊对这个地址赋值
                int mPositionHandle = GLES20.glGetAttribLocation(mProgram,"vPosition");

                // 绑定vertex坐标值 调用glVertexAttribPointer()告诉OpenGL，它可以在
                // 缓冲区vertexBuffer中获取vPosition的数据
                GLES20.glVertexAttribPointer(mPositionHandle, 3,
                        GLES20.GL_FLOAT, false,
                        3*4, fb);

                // 启用vertex Enable a handle to the triangle vertices
                GLES20.glEnableVertexAttribArray(mPositionHandle);

                // get handle to fragment shader's vColor member
                int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

                // Set color for drawing the triangle
                GLES20.glUniform4fv(mColorHandle, 1, color, 0);

                // 通过 GLES20.glDrawArrays 或者 GLES20.glDrawElements 开始绘制
                GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, coords.length/3);

                // Disable vertex array
                GLES20.glDisableVertexAttribArray(mPositionHandle);
            }
        });

        // Set the RenderMode
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

        setContentView(glSurfaceView);
    }

    /**
     * 加载并编译着色器代码
     * 渲染器类型type={GLES20.GL_VERTEX_SHADER, GLES20.GL_FRAGMENT_SHADER}
     * 渲染器代码 GLSL
     */
    public int loadShader(int type,String shaderCode)
    {
        int shader = GLES20.glCreateShader(type);
        //加载shader代码 glShaderSource 和 glCompileShader
        GLES20.glShaderSource(shader,shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }
}
